package com.zzw.conf;

import com.github.pagehelper.PageHelper;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
@AutoConfigureAfter(DruidDataSourcesConfig.class)
@EnableTransactionManagement
/**
* @Athor:xiezhongjiang
* @Description:mybatis配置
* @Date:2017/10/26 11:39
* @Since:1.0.0
*/
public class MybatisConfig implements TransactionManagementConfigurer {
    @Resource(name = "dataSource")
    DataSource dataSource;
    @Autowired
    private MybatisPropertis mybatisPropertis;

    /**
     * 可以通过这个类,详细配置mybatis
     *
     * @return
     */
//    @Bean
    
//    public org.apache.ibatis.session.Configuration mybatisSetting(){
//        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
//        return configuration;
//    }
    @Bean(name = "sqlSessionFactory")
    /**
    * @Athor:xiezhongjiang
    * @Description:sqlfactory
    * @Date:2017/10/26 11:41
    * @Param:[]
    * @return org.apache.ibatis.session.SqlSessionFactory
    */
    public SqlSessionFactory sqlSessionFactoryBean() {

        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage(mybatisPropertis.getTypeAliasesPackage());
        //添加插件
        bean.setPlugins(new Interceptor[]{pageHelper(),sqlPrintInterceptor()});

        //添加XML目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
            return bean.getObject();
        } catch (Exception e) {
            throw new RuntimeException("sqlSessionFactory init fail", e);
        }
    }

    @Bean(name = "sqlSessionTemplate")
    /**
    * @Athor:xiezhongjiang
    * @Description:用于实际查询的sql工具,传统dao开发形式可以使用这个,基于mapper代理则不需要注入
    * @Date:2017/10/26 11:41
    * @Param:[sqlSessionFactory]
    * @return org.mybatis.spring.SqlSessionTemplate
    */
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "transactionManager")
    @Override
    /**
    * @Athor:xiezhongjiang
    * @Description:事务管理,具体使用在service层加入@Transactional注解
    * @Date:2017/10/26 11:42
    * @Param:[]
    * @return org.springframework.transaction.PlatformTransactionManager
    */
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    /**
     * @Athor:xiezhongjiang
     * @Description:将要执行的sql进行日志打印(不想拦截，就把这方法注释掉)
     * @Date:2017/10/26 10:16
     * @Param:[]
     * @return com.zzw.conf.SqlPrintInterceptor
     */
    public SqlPrintInterceptor sqlPrintInterceptor(){
        return new SqlPrintInterceptor();
    }


//        <!-- 分页插件 -->
//      <plugins>
//                    <plugin interceptor="com.github.pagehelper.PageHelper">
//                            <property name="dialect" value="mysql"/>
//                            <!-- 该参数默认为false -->
//                              <!-- 设置为true时，会将RowBounds第一个参数offset当成pageNum页码使用 -->
//                              <!-- 和startPage中的pageNum效果一样 -->
//                            <property name="offsetAsPageNum" value="true"/>
//                             <!-- 该参数默认为false -->
//                              <!-- 设置为true时，使用RowBounds分页会进行count查询 -->
//                            <property name="rowBoundsWithCount" value="true"/>
//                            <!-- 设置为true时，如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
//                              <!-- （相当于没有执行分页查询，但是返回结果仍然是Page类型） -->
//                            <property name="pageSizeZero" value="true"/>
//                            <!-- 3.3.0版本可用 - 分页参数合理化，默认false禁用 -->
//                              <!-- 启用合理化时，如果pageNum<1会查询第一页，如果pageNum>pages会查询最后一页 -->
//                              <!-- 禁用合理化时，如果pageNum<1或pageNum>pages会返回空数据 -->
//                            <property name="reasonable" value="false"/>
//                            <!-- 支持通过Mapper接口参数来传递分页参数 -->
//                            <property name="supportMethodsArguments" value="false"/>
//                            <!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
//                            <property name="returnPageInfo" value="none"/>
//
//                   </plugin>
//          </plugins>
    @Bean
    /**
    * @Athor:xiezhongjiang
    * @Description:分页插件
    * @Date:2017/10/26 11:43
    * @Param:[]
    * @return com.github.pagehelper.PageHelper
    */
    public PageHelper pageHelper() {
        PageHelper pageHelper = new PageHelper();
        Properties p = new Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        p.setProperty("returnPageInfo", "check");
        p.setProperty("params", "count=countSql");
        pageHelper.setProperties(p);
        return pageHelper;
    }

}
